//#include <glad/glad.h>
//#include <GLFW/glfw3.h>
//
// // 顶点着色器源码
// const char* vertexShaderSource = R"(
//     #version 330 core
//     layout (location = 0) in vec3 aPos;
//     void main()
//     {
//         gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
//     }
// )";
//
// // 片段着色器源码
// const char* fragmentShaderSource = R"(
//     #version 330 core
//     out vec4 FragColor;
//     void main()
//     {
//         FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
//     }
// )";
//
// int main()
// {
//     // 初始化GLFW
//     glfwInit();
//     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
//     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//
//     // 创建一个窗口对象
//     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", NULL, NULL);
//     if (window == NULL)
//     {
//         std::cout << "Failed to create GLFW window" << std::endl;
//         glfwTerminate();
//         return -1;
//     }
//     glfwMakeContextCurrent(window);
//
//     // 初始化GLAD
//     if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
//     {
//         std::cout << "Failed to initialize GLAD" << std::endl;
//         return -1;
//     }
//
//     // 编译顶点着色器
//     unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
//     glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
//     glCompileShader(vertexShader);
//
//     // 编译片段着色器
//     unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
//     glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
//     glCompileShader(fragmentShader);
//
//     // 链接着色器程序
//     unsigned int shaderProgram = glCreateProgram();
//     glAttachShader(shaderProgram, vertexShader);
//     glAttachShader(shaderProgram, fragmentShader);
//     glLinkProgram(shaderProgram);
//
//     // 删除着色器
//     glDeleteShader(vertexShader);
//     glDeleteShader(fragmentShader);
//
//     // 设置顶点数据（这里我们只绘制一个三角形）
//     float vertices[] = {
//             0.5f,  0.5f, 0.0f,  // 右上角
//             0.5f, -0.5f, 0.0f,  // 右下角
//             -0.5f, -0.5f, 0.0f,  // 左下角
//     };
//     unsigned int VBO, VAO;
//     glGenVertexArrays(1, &VAO);
//     glGenBuffers(1, &VBO);
//     glBindVertexArray(VAO);
//     glBindBuffer(GL_ARRAY_BUFFER, VBO);
//     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
//     glEnableVertexAttribArray(0);
//
//     // 渲染循环
//     while (!glfwWindowShouldClose(window))
//     {
//         glClear(GL_COLOR_BUFFER_BIT);
//         glUseProgram(shaderProgram);
//         glBindVertexArray(VAO);
//         glDrawArrays(GL_TRIANGLES, 0, 3);
//         glfwSwapBuffers(window);
//         glfwPollEvents();
//     }
//
//     // 清理资源
//     glDeleteVertexArrays(1, &VAO);
//     glDeleteBuffers(1, &VBO);
//     glDeleteProgram(shaderProgram);
//
//     // 终止GLFW
//     glfwTerminate();
//     return 0;
// }

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <iostream>
#include "glm/gtc/type_ptr.hpp"

#include "include/tools/ShaderLoader.cpp"
#include "include/tools/structs/shader_program.h"
// // 顶点着色器源码
// auto vertexShaderSource = R"(
//     #version 330 core
//     layout (location = 0) in vec3 aPos;
//     layout (location = 1) in vec3 aColor;
//     uniform mat4 model;
//     uniform mat4 view;
//     uniform mat4 projection;
//     out vec3 color;
//     void main()
//     {
//         gl_Position = projection * view * model * vec4(aPos, 1.0);
//         color = aColor;
//     }
// )";
//
// // 片段着色器源码
// auto fragmentShaderSource = R"(
//     #version 330 core
//     in vec3 color;
//     out vec4 FragColor;
//     void main()
//     {
//         FragColor = vec4(color, 1.0);
//     }
// )";

int main()
{
    shader_program * shader_program = ShaderLoader::load_shader("chapter1", "chapter_1");
    std::cout << shader_program -> fragment_code << std::endl;
    std::cout << shader_program -> vertex_code << std::endl;
    // 初始化GLFW
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    // 创建一个窗口对象
    GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", nullptr, nullptr);
    if (window == nullptr)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // 初始化GLAD
    if (!gladLoadGLLoader(reinterpret_cast<GLADloadproc>(glfwGetProcAddress)))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    // 编译顶点着色器
    const unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, shader_program -> vertex_code, nullptr);
    glCompileShader(vertexShader);

    // 编译片段着色器
    const unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, shader_program -> fragment_code, nullptr);
    glCompileShader(fragmentShader);

    // 链接着色器程序
    const unsigned int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    // 删除着色器
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    // 设置顶点数据（这里我们只绘制一个彩色的三角形）
    constexpr float vertices[] = {
            0.0f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,  // 顶部顶点，红色
            -0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,  // 左下角顶点，绿色
            0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f   // 右下角顶点，蓝色
    };
    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), static_cast<void *>(nullptr));
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), reinterpret_cast<void *>(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    // 设置投影矩阵
    glm::mat4 projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f);

    // 渲染循环
    while (!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glUseProgram(shaderProgram);

        // 设置视图矩阵
        glm::mat4 view = lookAt(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

        // 设置模型矩阵
        glm::mat4 model = glm::mat4(1.0f);
        model = rotate(model, static_cast<float>(glfwGetTime()), glm::vec3(0.0f, 1.0f, 0.0f));

        // 设置着色器uniform变量
        const unsigned int modelLoc = glGetUniformLocation(shaderProgram, "model");
        const unsigned int viewLoc = glGetUniformLocation(shaderProgram, "view");
        const unsigned int projectionLoc = glGetUniformLocation(shaderProgram, "projection");
        glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));

        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glBindVertexArray(0);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // 清理资源
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteProgram(shaderProgram);

    // 终止GLFW
    glfwTerminate();
    // return 0;
    return 0;
}